package com.coolcode.aspect;

import com.coolcode.anno.ParamValid;
import com.coolcode.enums.ExceptionErrorCode;
import com.coolcode.exception.ValidationException;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.util.ArrayList;
import java.util.List;

@Aspect
@Component
public class ParamValidAspect {

    @Before("@annotation(paramValid)")
    public void paramValid(JoinPoint point, ParamValid paramValid) {

        Object[] paramObj = point.getArgs();
        if (paramObj.length > 1 && paramObj[1] instanceof BindingResult) {
            BindingResult bindingResult = (BindingResult) paramObj[1];

            if (bindingResult == null || !bindingResult.hasErrors()) {
                return;
            }
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            ArrayList<String> messages = new ArrayList<>();
            for (ObjectError objectError : allErrors) {
                if (objectError instanceof FieldError) {
                    FieldError fieldError = (FieldError) objectError;
                    messages.add(fieldError.getField() + " " + fieldError.getDefaultMessage());
                } else {
                    messages.add(objectError.getDefaultMessage());
                }
            }

            throw new ValidationException(ExceptionErrorCode.INVALID_INPUT.getCode(),
                    String.format(ExceptionErrorCode.INVALID_INPUT.getDesc(), StringUtils.join(messages, "|")));
        }
    }
}
